<?php
/**
 * the sax xml reader
 * @author Chayakon PONGSIRI
 * @example
 *
 * the xml data file
 * <root>
 *  <businesse> <--- the element name that specified in readNextNode
 *    <id>...
 *    <name>...
 *  </businesse>
 * </root> 
 * 
 * $sax = new SAXReader("export.xml");
 * print_r($sax->readNextNode("businesse"));
 * print_r($sax->readNextNode("businesse"));
 * $sax->close();
 */
class SAXReader{
  var $reader = null;
  var $is_open = false;
  var $is_valid = true;
  /**
   * SAXReader constructor
   * @param string  file name with full path of xml file
   */
  function SAXReader($file = null){
    $this->reader = new XMLReader();
    if ($file != null){
      $this->is_open = $this->reader->open($file);
      $this->is_valid = $this->is_open;
    }
  }
  
  /**
  * set direct data to parse
  */
  function setXml($data){
    if (!empty($data)){
      $this->is_open = $this->reader->XML($data);
      $this->is_valid = $this->is_open;
    }
  }
  /**
   * read the xml element as array
   * @param string the xml element name to start or stop parse,
   *                usaly below root element
   * @return array [by_ref] the array of data
   */
  function &readNextNode($nodeName){
    //if not open
    if (!$this->is_open && empty($nodeName)){
      $this->is_valid = false;
      return false;
    }
    $reader = $this->reader;
    $data = array();
    //read and skip other node
    while ($reader->read()) {
      if ($reader->nodeType == XMLREADER::ELEMENT){
        if ($reader->localName == $nodeName){
          break;
        }
      }
    }
    //read all data in node
    while ($reader->read()) {
      if ($reader->nodeType == XMLREADER::ELEMENT){
        $name = $reader->localName;
        $reader->read();
        $value = $reader->value;
        $data[$name] = $value;
        //echo "$name , $value <br/>";
      }else if ($reader->nodeType == XMLREADER::END_ELEMENT){
        //break at end element
        if ($reader->localName == $nodeName){
          break;
        }
      }
    }
    if (count($data) <= 0){
      $this->is_valid = false;
      return false;
    }
    return $data;
  }
  function isValid(){
    return $this->is_valid;
  }
  function close(){
    if ($this->reader){
      $this->reader->close();
    }
  }
}